import Core.MongoDB as MongoDB
import Core.Gadget as Gadget
import Core.IO as IO
import Core.WindFunctions as Wind
import Core.DataSeries as DataSeries
import Core.Global as Global
from datetime import *
import numpy as np
import pandas as pd
import math
import copy
import DataProcess
from DataProcess import *
from DataProcess.Download_Stock_Fundamental_Utility import *


# Cold Start
def Batch_Download_Fundamentals(database, datetime1, datetime2, instruments=[], startIndex=0, logger=None):
    reportDateTimes = Gadget.GenerateReportDates(datetime1, datetime2)
    #
    if len(instruments) == 0:
        instruments = database.Find("Instruments", "Stock")
    #
    count = 0
    for instrument in instruments:
        count += 1
        if instrument["Symbol"] == "002588.SZ":
            a = 0
        if count == 1096:
            b = 0
        if count == 1098:
            b = 0
    #
    Download_Data_ByDate(database, instruments, reportDateTimes, Download_Fundamentals, startIndex, logger=logger)


def Batch_Download_Fundamentals_Adv(database, datetime1, datetime2, forceToUpdate=False, startIndex=0, logger=None):
    #
    instruments = database.Find("Instruments", "Stock")
    #
    count = 0
    for instrument in instruments:
        instrument["DateTime1"] = instrument["datetime1"]
        instrument["DateTime2"] = instrument["datetime2"]
        instrument["Symbol"] = instrument["symbol"]
        #
        symbol = instrument["symbol"]
        count = count + 1
        #
        if count < startIndex:
            continue
        #
        print("")
        print("Download_Fundamentals_Adv", symbol, "count", str(count), "@", datetime.now())
        #
        if instrument["datetime2"] < datetime1:
            print(symbol, "Delisted before", datetime1)
            continue
        #
        realDateTime1, realDateTime2 = DataProcess.DeterminRange(instrument, datetime1, datetime2)

        # 确认需要更新的ReportDate
        missingReportDates = []
        if forceToUpdate: # 强制更新
            missingReportDates = Gadget.GenerateReportDates(realDateTime1, realDateTime2)
        else: # 去重更新
            missingReportDates = DataProcess.CheckMissingReportbyInstrument(database, instrument, realDateTime1, realDateTime2)

        if len(missingReportDates) == 0:
            print(symbol + " Complete")
            continue
        #
        for reportDate in missingReportDates:
            # 尝试更新
            reportReady = TryToRequestFundamental(symbol, reportDate)
            # 有正常返回值则进行更新
            if reportReady:
                Download_Fundamentals(database, instrument, reportDate)
            # 当期无正常数值
            elif reportDate < instrument["DateTime1"]:
                print(symbol + " ReportTooEarly @" + str(reportDate))
            else:
                print(symbol + " ReportNotReady @" + str(reportDate))
            kkwood = 0
        endLoopDate = 0
    endLoopInstrument = 0


def Batch_Download_ShareHolder(database, datetime1, datetime2, startIndex=0):
    #
    reportDateTimes = Gadget.GenerateReportDates(datetime1, datetime2)
    instruments = database.Find("Instruments", "Stock")
    #
    Download_Data_ByDate(database, instruments, reportDateTimes, Download_SharesHolder, startIndex=startIndex)


def TryToRequestFundamental(symbol, reportDate):
    # ---
    contents = []
    contents.append("stm_issuingdate")
    # ---
    params = {}
    rptDateStr = Gadget.ToDateString(reportDate)
    params["rptDate"] = rptDateStr
    params["rptType"] = "1"
    params["priceAdj"] = "U"
    params["cycle"] = "D"

    # ---
    # print("Requesting @" + str(datetime.now()))
    values = Wind.WSS(symbol, contents, params)[0]

    minDate = datetime(1900,1,1)
    if values["stm_issuingdate"] < minDate:
        return False
    return True


# 返回要Request的字段
def FundamentalFields():
    #
    contents = []
    # ---2018-4-13 打乱数字顺序，按照逻辑顺序排列---

    # --- Income Statement ---
    # --- Total Revenue ---
    contents.append("tot_oper_rev")  # 0
    contents.append("oper_rev")  # 1

    # --- Total Expenses ---
    contents.append("tot_oper_cost")  # 2
    contents.append("oper_cost")  # 3 COGS
    #
    contents.append("fin_exp_is")  # 4 not in use
    contents.append("selling_dist_exp")  # 5
    contents.append("gerl_admin_exp")  # 6
    contents.append("taxes_surcharges_ops")  # 7
    contents.append("impair_loss_assets")  # 14 not in use
    # contents.append("int_exp")
    # contents.append("oper_exp")

    # ---Dep i ---
    contents.append("depr_fa_coga_dpba")  # 126
    contents.append("amort_intang_assets")  # 127
    contents.append("amort_lt_deferred_exp")  # 128
    # ---Dep ii --- 并不确定哪个更准确---
    contents.append("stmnote_others_7629")  # 109
    contents.append("stmnote_others_7628")  # 110
    # --- Interest Expense ---
    contents.append("stmnote_finexp_4")  # 134
    contents.append("stmnote_finexp_5")  # 135
    # --- Investment ---
    contents.append("net_invest_inc")  # 9

    # --- Operating Profit 2 营业利润 ---
    contents.append("opprofit")  # 8

    # --- Extraodinary ---
    contents.append("non_oper_rev")  # 10
    contents.append("non_oper_exp")  # 11
    contents.append("other_grants_inc") #其他收益
    contents.append("gain_asset_dispositions") #资产处置收益
    # add 2019-4-24
    contents.append("net_gain_chg_fv") #公允价值变动净收益
    contents.append("net_gain_fx_trans") #汇兑净收益
    contents.append("net_other_oper_inc") #其他业务净收益

    # ---Total Income 利润总额---
    contents.append("tot_profit")  # 12
    contents.append("tax")  # 13

    # ---Net Income1 净利润 ---
    contents.append("net_profit_is")  # 15
    contents.append("deductedprofit")  # 106 # not in use
    contents.append("minority_int_inc")  # 107
    # --- Net Income2 归母净利润 ---
    contents.append("np_belongto_parcomsh")  # 108

    # --- Assets ---
    contents.append("tot_assets")  # 16

    # --- Current Asstes---
    contents.append("tot_cur_assets")  # 17
    # --- Cash and Equivalents ---
    contents.append("monetary_cap")  # 18
    # --- Banking? ---
    contents.append("settle_rsrv")  # 19
    contents.append("cash_deposits_central_bank")  # 20
    contents.append("asset_dep_oth_banks_fin_inst")  # 21
    contents.append("precious_metals")  # 22
    contents.append("mrgn_paid")  # 23

    # ---Short-Term Investment ---
    contents.append("derivative_fin_assets")  # 27
    contents.append("tradable_fin_assets")  # 25
    contents.append("red_monetary_cap_for_sale")  # 26
    contents.append("rcv_invest")  # 28
    contents.append("loans_to_oth_banks")  # 24
    contents.append("fin_invest") # 金融投资 = 交易性金融资产 + 债券，权益，其他权益工具
    contents.append("hfs_assets") # 划分为持有待售的资产
    contents.append("fin_assets_chg_compreh_inc") # 以公允价值计量且其变动计入其他综合收益的金融资产
    contents.append("fin_assets_amortizedcost") # 以摊余成本计量的金融资产

    # ---Receivable---
    contents.append("notes_rcv")  # 29
    contents.append("acct_rcv")  # 30
    contents.append("int_rcv")  # 31
    contents.append("prem_rcv")  # 32
    contents.append("oth_rcv")  # 33

    # ---Prepaid Expense (Deferred expense)---
    contents.append("prepay")  # 34
    contents.append("deferred_tax_assets")  # 51

    # ---Inventory ---
    contents.append("inventories")  # 35

    # --- Other Current Assets ---
    contents.append("non_cur_assets_due_within_1y")  # 36
    contents.append("oth_cur_assets")  # 37

    # ---Non-Current Assets---
    contents.append("tot_non_cur_assets")  # 38
    # --- PPE ---
    contents.append("fix_assets")  # 39
    contents.append("const_in_prog")  # 40

    # ---LT Investment---
    contents.append("long_term_eqy_invest")  # 41
    contents.append("loans_and_adv_granted")  # 42
    contents.append("fin_assets_avail_for_sale")  # 43
    contents.append("held_to_mty_invest")  # 44
    contents.append("invest_real_estate")  # 45
    contents.append("time_deposits")  # 46
    contents.append("insured_pledge_loan")  # 47
    # --- Intangible ---
    contents.append("goodwill")  # 48
    contents.append("intang_assets")  # 49
    contents.append("r_and_d_costs")
    # --- Other Non-Current asset---
    contents.append("long_term_rec")  # 50
    contents.append("long_term_deferred_exp")  # 52
    contents.append("oth_non_cur_assets")
    contents.append("oth_assets")

    # --- Liability ---
    contents.append("tot_liab")  # 55
    contents.append("tot_cur_liab")  # 56

    # --- ST Debt ---
    contents.append("st_borrow")  # 57
    # --- Financial Institution?---
    contents.append("loans_oth_banks")  # 58
    contents.append("tradable_fin_liab")  # 59
    contents.append("fund_sales_fin_assets_rp")  # 60
    contents.append("liab_dep_oth_banks_fin_inst")  # 61
    contents.append("derivative_fin_liab")  # 62
    contents.append("cust_bank_dep")  # 63
    contents.append("insured_deposit_invest")  # 64
    contents.append("acting_trading_sec")  # 65
    contents.append("acting_uw_sec")  # 66
    contents.append("borrow_central_bank")
    # --- Payable ---
    contents.append("acct_payable")  # 67
    contents.append("empl_ben_payable")  # 68
    contents.append("dvd_payable")  # 69
    contents.append("int_payable")  # 70
    contents.append("taxes_surcharges_payable")  # 71
    contents.append("oth_payable")  # 72
    contents.append("notes_payable")  # 73
    contents.append("dvd_payable_insured")  # 74
    # --- Unearned revenue (Deferred revenue) ---
    contents.append("adv_from_cust")  # 75
    contents.append("prem_received_adv")  # 76
    contents.append("deferred_tax_liab")  # 86
    # --- Other Current Liabiity ---
    contents.append("non_cur_liab_due_within_1y")  # 77
    contents.append("oth_cur_liab")  # 78
    contents.append("agency_bus_liab")  # 79

    # --- Non-Current Liability---
    contents.append("tot_non_cur_liab")  # 80
    # ---LT Debt---
    contents.append("lt_borrow")  # 81
    contents.append("bonds_payable")  # 82
    contents.append("life_insur_rsrv")  # 83
    contents.append("lt_health_insur_v")  # 84
    # ---Other Non Current Liab ---
    contents.append("provisions")  # 85
    contents.append("deferred_inc_non_cur_liab")
    contents.append("oth_non_cur_liab")  # 87
    contents.append("oth_liab")  # 88

    # --- Equity ---
    contents.append("tot_equity")  # 89
    # --- Paid-in Capital ---
    contents.append("cap_stk")  # 90
    contents.append("other_equity_instruments_PRE")  # 优先股
    contents.append("tsy_stk")  # 91 # 库存股

    # --- Reserve ---
    contents.append("cap_rsrv")  # 93
    contents.append("surplus_rsrv")  # 94
    contents.append("prov_nom_risks")  # 95
    contents.append("special_rsrv")  # tradedate
    #
    contents.append("minority_int")  # 92
    contents.append("undistributed_profit")  # 96
    contents.append("other_compreh_inc_bs")  # tradedate

    # --- Cash Flow ---
    contents.append("net_cash_flows_oper_act")  # 97
    contents.append("net_cash_flows_inv_act")  # 98
    contents.append("net_cash_flows_fnc_act")  # 99
    # --- Capital Expenditure ---
    contents.append("cash_pay_acq_const_fiolta")  # 100
    # --- Sale PPE ---
    contents.append("net_cash_recp_disp_fiolta")  # 101
    # --- Debt Issurance ---
    contents.append("proc_issue_bonds")  # 102
    contents.append("cash_recp_borrow")  # 103
    # --- Debt Reduction ---
    contents.append("cash_prepay_amt_borr")  # 104
    # --- Equity Issurance ---
    contents.append("cash_recp_cap_contrib")  # 129
    # --- Equity Reduction ---
    contents.append("stot_cash_outflows_fnc_act")  # 133
    contents.append("cash_pay_dist_dpcp_int_exp")  # 105分配股利、利润或偿付利息支付的现金
    # --- ??? not in use ---
    contents.append("other_cash_recp_ral_fnc_act")  # 130
    contents.append("stot_cash_inflows_fnc_act")  # 131
    contents.append("other_cash_pay_ral_fnc_act")  # 132

    # --- Financial Analysis ---
    contents.append("workingcapital")  # 136
    contents.append("networkingcapital")  # 137
    contents.append("investcapital")
    contents.append("interestdebt")
    contents.append("tangibleasset")
    contents.append("retainedearnings")
    contents.append("exinterestdebt_current")
    contents.append("exinterestdebt_noncurrent")

    # --- Other ---
    contents.append("stm_issuingdate")  # 111
    contents.append("total_shares")  # 112
    contents.append("free_float_shares")  # 113
    contents.append("close")  # 125
    # contents.append("div_aualaccmdiv")#114

    # --- Financials ---
    contents.append("eps_basic")  # 115
    contents.append("eps_ttm")  # 116
    contents.append("bps")  # 117
    contents.append("ebitdatointerest")  # 121
    contents.append("netprofitmargin")  # 122
    contents.append("roe")  # 123
    contents.append("roa")  # 124

    # ---Trade Day 现在使用 rptDate也可以取到---
    contents.append("pe_ttm")  # 118
    contents.append("pb_lf")  # 119
    contents.append("ps_ttm")  # 120

    # 20200422 扩展字段
    contents.append("rd_exp")

    #
    # contents.append("segment_sales")

    return contents


#---从wind Request 财务报表 大约138个基础财务数据---
def Download_Fundamentals_Basic(database, symbol, reportDate):
    # 获取所有字段
    fields = FundamentalFields()

    # 生成部分参数
    yearStr = str(reportDate.year-1)
    rptDateStr = Gadget.ToDateString(reportDate)

    # 建造参数
    params = {}
    params["rptDate"] = rptDateStr
    # params["endDate"] = rptDateStr #total_shares 不再依赖
    # params["year"] = yearStr # div_aualaccmdiv 不再使用该数据
    params["currencyType"] = "BB"  # eps_basic 依赖
    params["rptType"] = "1"
    params["priceAdj"] = "U"
    params["tradeDate"] = rptDateStr # Close 所需参数
    params["cycle"] = "D"
    params["order"] = "2"  # segmeng_Sales的参数

    #
    value = Download_Fundamentals_Fields(database, symbol, reportDate, fields=fields, params=params, isUpdate=False)
    print("Saved Fundamentals_Basic", symbol, reportDate.date())
    return value



def Download_Fundamentals_Fields(database, symbol, reportDate,
                                 fields=[], params={},
                                 isUpdate=True): # update 旧文档还是生成新文档

    # 统一转换为Date
    if isinstance(reportDate, datetime):
        reportDate = reportDate.date()

    # ---Field----
    if "stm_issuingdate" not in fields:
        fields.append("stm_issuingdate")

    # ---Necessary Parameters---
    params["currencyType"] = "BB"
    params["rptType"] = "1"
    params["rptDate"] = Gadget.ToDateString(reportDate)

    # ---Request Functions---
    values = Wind.WSS(symbol, fields, params)[0]

    # ---ReleaseDate 一定大于 ReportDate，用此特性来检查数据是都正常 ---
    if values["stm_issuingdate"].date() < reportDate: # fund.ReleaseDate < datetime
        print("ParseFundamental: Release Data Not Correct Parsed : " + symbol + " @ReportDate " + str(reportDate));
        if symbol == "300372.SZ": #---新泰电器最后一期财报，没有发布日
            values["stm_issuingdate"] = reportDate + timedelta(days=30)
        else:
            return False

    #
    dataObject = {}
    for k, v in values.items():
        # if k == "segment_sales": # Sales 应该另行处理
        #     continue
        dataObject[k] = values[k]

    # ---if Create New Document---
    if not isUpdate:
        dataObject["Period"] = Gadget.ReportPeriod(reportDate)
        dataObject["Symbol"] = symbol
        dataObject["Report_Date"] = reportDate # Gadget.ToDateTimeString(reportDate)
        releaseDateTime = values["stm_issuingdate"]
        releaseDateTime = releaseDateTime.replace(microsecond=0)  # Dirty Datetime
        dataObject["Release_Date"] = releaseDateTime.date()
        dataObject["DateTime"] = releaseDateTime # Gadget.ToDateTimeString(releaseDateTime)
        dataObject["UTC_DateTime"] = Gadget.ToUTCDateTime(releaseDateTime)
        dataObject["Key"] = symbol + "_Fundamental_" + Gadget.ToDateString(reportDate)

    # ---Target To Update---
    target = {}
    target["Report_Date"] = reportDate
    target["Symbol"] = symbol

    #
    if isUpdate:
        database.Update("Financial_Data", "Stock_Fundamental_Basic", target, dataObject)
    else:
        database.Upsert("Financial_Data", "Stock_Fundamental_Basic", target, dataObject)

    #
    return True


# ---机构持股信息---
def Download_InstituteHolding(database, symbol, reportDate):

    collectionName = symbol + "_Fundamental"

    # ---Field----
    contents = []
    # 之后请补齐
    # contents.append("holder_top10quantity")#tradedate
    # contents.append("holder_top10liqquantity")#tradedate
    #
    contents.append("holder_totalbyinst")   #rptdate 机构持股
    contents.append("holder_totalbygeneralcorp")    #rptdate 一般法人持股
    contents.append("holder_totalbyfund")   #rptdate 公募基金持股
    contents.append("holder_totalbybywmp")  # rptdate 券商集合理财持股数量
    contents.append("holder_totalbybysec")  # rptdate 券商持股数量
    contents.append("holder_totalbyinsur")  # rptdate 保险公司持股数量
    contents.append("stm_issuingdate")

    # ---Necessary Parameters---
    params = {}
    datestr = Gadget.ToDateString(reportDate)
    params["tradeDate"] = datestr
    params["rptDate"] = datestr

    # ---Request Functions---
    values = Wind.WSS(symbol, contents, params)[0]

    dataObject = {}
    for k, v in values.items():
        # s = "Wind." + k
        # dataObject[s] = values[k]
        if k == "stm_issuingdate":
            continue
        dataObject[k] = values[k]

    dataObject["Period"] = Gadget.ReportPeriod(reportDate)
    dataObject["Report_Date"] = reportDate  # Gadget.ToDateTimeString(reportDate)
    releaseDateTime = values["stm_issuingdate"]
    releaseDateTime = releaseDateTime.replace(microsecond=0)  # Dirty Datetime

    dataObject["Release_Date"] = releaseDateTime  # Gadget.ToDateTimeString(releaseDateTime)
    dataObject["DateTime"] = releaseDateTime  # Gadget.ToDateTimeString(releaseDateTime)
    dataObject["Date"] = releaseDateTime.date()

    # if releaseDateTime < datetime(1900,1,1):
    #     dataObject["UTCDateTime"] = releaseDateTime
    # else:
    #     dataObject["UTCDateTime"] = Gadget.ToUTCDateTime(releaseDateTime)

    dataObject["Symbol"] = symbol
    dataObject["Key2"] = symbol + "_Fundamental_" + Gadget.ToDateString(reportDate)

    # ---Upsert to Database---
    target = {}
    target["ReportDate"] = reportDate
    target["Symbol"] = symbol
    database.Upsert("Stock", "Institute_Holding", target, dataObject)
    #
    print("Saved Institute_Holding", symbol, reportDate.date())
    pass
    # ---


#
def ProcessSaveShareHolderData(database, symbol, data, reportDate, releaseDate, tableName):
    #
    # releaseDate = params.get("ReleaseDate")
    # if releaseDate == None:
    #     filter = {"Symbol": symbol, "ReportDate": reportDate}
    #     fund = database.Find("Stock", "Fundamental", filter)
    #     if len(fund) > 0:
    #         releaseDate = fund[0]["DateTime"]
    #         params["ReleaseDate"] = releaseDate
    #     else:
    #         print("Can't Find ReleaseDate", symbol, releaseDate)

    period = Gadget.ReportPeriod(reportDate)

    # public data
    tempDoc = {}
    # tempDoc["UTCDateTime"] = Gadget.ToUTCDateTime(releaseDate)
    tempDoc["DateTime"] = releaseDate
    tempDoc["Date"] = releaseDate
    tempDoc["Release_Date"] = releaseDate.date()
    tempDoc["Report_Date"] = reportDate.date()
    tempDoc["Symbol"] = symbol
    tempDoc["Period"] = period

    # loop Share Holder
    holders = []
    count = 0
    for d in data:
        entry = copy.deepcopy(tempDoc)
        if "name" not in d:
            a = 0
        entry["Holder_Name"] = d["name"]
        amount = d["amount"] * 10000
        if amount > 10000000000000000000: # 19
            entry["Amount"] = None
        else:
            entry["Amount"] = amount

        entry["Ratio"] = d["ratio"]
        #
        if "type" in d:
            entry["Share_Type"] = d["type"]
        #
        entry["Ranking"] = int(count)
        entry["Key2"] = symbol + "_" + Gadget.ToDateString(reportDate) + "_" + str(count)
        #
        holders.append(entry)
        count += 1

    # ---Upsert---
    database.Upsert_Many("Stock", tableName, [], holders)
    pass

#
def PeriodToChinese(period):
    sPeriod = ""
    if period == 1:
        sPeriod = "一季报"
    elif period == 2:
        sPeriod = "中报"
    elif period == 3:
        sPeriod = "三季报"
    elif period == 4:
        sPeriod = "年报"
    return sPeriod

#
def Download_SharesHolder_Sub(database, symbol, reportDate, command, logger=None):
    #
    # config = Config.Config()
    # logger = config.Logger("WindFundamental")

    #
    fields = ""
    rptDateStr = Gadget.ToDateString(reportDate)
    if command == "top10liqshareholders":
        fields = "name,amount,ratio"
        tableName = "top10_liqshareholder"
    elif command == "top10shareholders":
        fields = "name,amount,ratio,type"
        tableName = "top10_shareholder"
    else:
        return

    # Params
    params = {}
    params["rptdate"] = rptDateStr
    params["windcode"] = symbol
    params["year"] = reportDate.year
    period = Gadget.ReportPeriod(reportDate)
    sPeriod = PeriodToChinese(period)
    params["period"] = sPeriod

    # ---注意：单位万股---
    # params["field"] = "name,amount,ratio"  / "name,amount,ratio,type"
    params["field"] = fields
    data = Wind.WSET(command, params)
    #
    if data == None:
        print(symbol, command, " NoData ", params["rptdate"])
        if logger:
            logger.info(symbol + " " + command + " NoData " + str(reportDate))
        return
    #
    # 补充发布日
    releaseDate = Wind.w.wss(symbol, "stm_issuingdate", "rptDate=" + rptDateStr)
    releaseDate = releaseDate.Data[0][0]
    minDate = datetime(1900,1,1)
    if releaseDate < minDate:
        print("Download_SharesHolder_Sub", command, "Can't Find Release Date", symbol, reportDate.date())
        return

    #
    ProcessSaveShareHolderData(database, symbol, data, reportDate, releaseDate, tableName)
    print("Saved", command, symbol, reportDate.date())

    a = 0


# 前十大股东
def Download_Top10SharesHolder(database, symbol, reportDate):
    Download_SharesHolder_Sub(database, symbol, reportDate, command="top10shareholders")


# 前十大流通股股东
def Download_Top10LiqSharesHolder(database, symbol, reportDate):
    Download_SharesHolder_Sub(database, symbol, reportDate, command="top10liqshareholders")


# 下载 Fundamental 前十大股东
def Download_SharesHolder(database, symbol, reportDate):
    # ---前十大流通股股东列表---
    # ---2013年前只有年报，半年报才公布股东---
    Download_Top10SharesHolder(database, symbol, reportDate)
    Download_Top10LiqSharesHolder(database, symbol, reportDate)


# 下载一个完整的 Financial Report
def Download_Fundamentals(database, instrument, reportDate, logger=None):
    #
    symbol = instrument["symbol"]
    print("DownloadFinancialReport ", symbol, reportDate.date())

    # 基础财务信息
    Download_Fundamentals_Basic(database, symbol, reportDate)

    # ---ReleaseDate Error 可能出现的错误---
    # 000022.SZ
    # 000522.SZ
    # 000562.SZ
    # 000602.SZ 2013-06-30
    # 300177.SZ 20170630 数据缺失

    # 机构持股信息
    Download_InstituteHolding(database, symbol, reportDate)

    # 大股东持股结构
    Download_SharesHolder(database, symbol, reportDate)

    # Sales 收入结构

    # 清洗报表 最终存入Fundamental
    FormatingReport(database, instrument, reportDate)
    pass


def FormatingReport(database, instrument, reportDate):
    #
    symbol = instrument["symbol"]
    target = {"Symbol": symbol, "Report_Date": reportDate.date()}
    fundamentals = database.Find("Stock", "Fundamental_Basic", target)
    #
    if len(fundamentals) == 0:
        print(symbol, reportDate, "Error No_Fundamental_Basic_Data")
        return
    finnacialReport = fundamentals[0]
    reportDate = finnacialReport["report_date"]

    # 检查是否无效数据太多
    countNone = 0
    for k,v in finnacialReport.items():
        if v == None:
            countNone += 1
    #
    if countNone > 150:
        print(symbol, reportDate, "Error Incomplete_Fundamental_Basic_Data")
    else:
        values = ProcessFundamentalAsCommonFormat(instrument, reportDate, finnacialReport)
        #
        for key, value in values.items():
            if str(value) == "nan":
                values[key] = None
        #
        values["Symbol"] = symbol
        values["Key2"] = symbol + "_Fundamental_" + Gadget.ToDateString(reportDate)
        values["Period"] = finnacialReport["period"]
        values["Report_Date"] = finnacialReport["report_date"]
        values["DateTime"] = finnacialReport["datetime"]
        values["UTC_DateTime"] = finnacialReport["utc_datetime"]
        values["Release_Date"] = finnacialReport["release_date"]
        database.Upsert("Stock", "Fundamental", {}, values)
        #
        print("Saved Fundamental", symbol, reportDate)
        pass


def FormatingReports(database, instruments, reportDatetime1=None, reportDatetime2=None):

    missingReports = MissingReports()
    start = False
    count = 0
    for instrument in instruments:
        count += 1
        symbol = instrument["Symbol"]
        print("Processing " + str(count))

        #if symbol == "601519.SH":
        #    start = True
        #if start == False:
        #    continue

        # ---Time Range---
        query = {}
        query["StdReportDate"] = {}
        if reportDatetime1 != None:
            query["StdReportDate"]["$gte"] = reportDatetime1
        if reportDatetime2 != None:
            query["StdReportDate"]["$lte"] = reportDatetime2
        if not query["StdReportDate"]:
            del query["StdReportDate"]

        # ---Load DataBase---
        fundamentals = database.find("Fundamental", symbol + "_Fundamental", query = query)
        for fund in fundamentals:
            reportDate = fund["ReportDate"]
            print(symbol + " Report @" + reportDate)
            #
            if symbol == "T00018.SH" and reportDate == "2006-09-30 00:00:00.000":
                kkwood = 0

            missing = False
            if "Wind" not in fund:
                print(symbol + " " + reportDate + " Error NoWindData")
                continue
            #if len(fund["Wind"]) < 150:
            #    print(symbol + " " + reportDate + " Error ImcompletedWindData @" + reportDate)
            #    continue

            for missingReport in missingReports:
                missingSymbol = missingReport["Symbol"]
                missingReportDate = missingReport["ReportDate"]
                if missingSymbol == symbol:
                    reportDateTime = Gadget.ParseDateTime(reportDate)
                    if reportDateTime == missingReportDate:
                        print(symbol + " " + reportDate + " Known Missing Report, Not Process")
                        missing = True

            if missing:
                continue

            fund = ProcessFundamentalAsCommonFormat(instrument, fund["ReportDate"], fund["Wind"])

            #---Convert Financials---
            values = {}
            for k,v in fund.items():
                s = "Values." + k
                values[s] = fund[k]

            #---Upsert To Datavase---
            target = {"ReportDate":reportDate}
            database.Upsert("Fundamental", symbol + "_Fundamental", target, values)


# 短期投资
def Calc_STInvest(document):
    # 拆出资金
    # "fin_invest" = 金融投资
    # + tradable_fin_assets 交易性金融资产
    # + debt_invest 债权投资
    # + oth_debt_invest 其他债权投资
    # + oth_eqy_instruments_invest 其他权益哦

    if document["fin_invest"] != 0:
        value = document["fin_invest"] + \
                document["loans_to_oth_banks"] + \
                document["red_monetary_cap_for_sale"] + \
                document["derivative_fin_assets"] + \
                document["rcv_invest"] + \
                document["hfs_assets"] + \
                document["fin_assets_chg_compreh_inc"] + \
                document["fin_assets_amortizedcost"]
    else:
        value = \
                document["tradable_fin_assets"] + \
                document["loans_to_oth_banks"] + \
                document["red_monetary_cap_for_sale"] + \
                document["derivative_fin_assets"] + \
                document["rcv_invest"] + \
                document["hfs_assets"] + \
                document["fin_assets_chg_compreh_inc"] + \
                document["fin_assets_amortizedcost"]
    #
    return value


# ---把Wind数据，清洗，标准化---
def ProcessFundamentalAsCommonFormat(instrument, reportDate, values):
    #
    symbol = instrument["symbol"]
    industry = instrument["cs_industry1"]
    #
    if reportDate == "2017-12-31 00:00:00.000":
        kkwood = 0
    #
    if "tot_oper_rev" not in values:
        print(symbol + " " + reportDate + " Error Incomplete_Fundamental_Basic_Data")
        return None

    if symbol == "000613.SZ" and reportDate == "2018-03-31 00:00:00.000":
        pass

    for key, val in values.items():
        if val is None:
            values[key] = 0

    fund = {}
    # ---Parse Fundamental Data---
    # ---Income Statement---
    fund["TotalRevenue"] = values["tot_oper_rev"]
    fund["Sales"] = values["oper_rev"]
    fund["TotalExpense"] = values["tot_oper_cost"] # ---银行为空, 2018.4 已经有数据---
    fund["COGS"] = values["oper_cost"] # ---银行为空
    fund["SGA"] = values["selling_dist_exp"] + values["gerl_admin_exp"] + values["taxes_surcharges_ops"];
    #包含了折旧

    fund["DepAmort"] = values["depr_fa_coga_dpba"] + values["amort_intang_assets"] + values["amort_lt_deferred_exp"];
    # values[109] + values[110];#这个项目下的Dep经常没数，所以用上面的代替

    fund["InterestExpense"] = values["stmnote_finexp_4"] - values["stmnote_finexp_5"];#values[4];
    fund["InvestIncome"] = values["net_invest_inc"];

    # --- Extraordinary ---
    ext1 = values["non_oper_rev"] - values["non_oper_exp"]
    ext2 = + values["other_grants_inc"] \
           + values["net_gain_chg_fv"] \
           + values["gain_asset_dispositions"] \
           + values["net_gain_fx_trans"]
    fund["Extraordinary"] = ext1 + ext2

    # --- Total Expense 包含所有（Dep && Interest Expense）---
    # --- OperatingProfit1 = Total Rev - Total Exp + Interest
    # --- OperatingProfit2  = Total Rev - Total Exp(include Dep Int)  + Investment
    # (OperatingProfit1 - Interest + Invest = OperatingProfit2)

    # --- OperatingProfit (Wind opprofit) = OperatingProfit2 + some Exraodianry (ex2)
    # --- eitda = operatingProfit1 + dep

    # ---OperatingProfit + ext1 = TotalIncome---

    fund["OperatingProfit"] = values["opprofit"]

    # ---For Financail Company---
    if industry == "银行" or industry == "非银行金融":
        print(symbol, reportDate, "Formatting 银行 or 非银行金融")

        # 2019-4-28 更新算法
        # 对于银行和非银机构，投资收益，利息和兑汇收益根本无法剥离
        fund["OperatingProfit1"] = values["opprofit"]
        fund["OperatingProfit2"] = values["opprofit"]

        #
        fund["TotalExpense"] = values["tot_oper_cost"]
        fund["GrossProfit"] = values["tot_oper_rev"] - values["tot_oper_cost"]; # 简单处理
    else:
        # 2019-4-28 更新算法

        # ---正向计算---
        op1Forward = values["tot_oper_rev"] - values["tot_oper_cost"] + fund["InterestExpense"]  # 多减去了利息，加回来
        op2Forward = values["tot_oper_rev"] - values["tot_oper_cost"] + values["net_invest_inc"]  # 在已经减去了利息的同时，加上投资收益

        # ---反向计算--- 更准确一些
        op2Backword = values["opprofit"] - ext2
        op1Backword = op2Backword + fund["InterestExpense"] - fund["InvestIncome"]

        # if operatingProfit2a != operatingProfit2b:
        #    print("OperatingProfit2 Not Identical " + symbol + " @ReportDate " + reportDate)
        fund["OperatingProfit1"] = op1Forward
        fund["OperatingProfit2"] = op2Forward
        #
        fund["GrossProfit"] = fund["Sales"] - fund["COGS"]

    #
    fund["TotalIncome"] = values["tot_profit"]; # 利润总额
    fund["Tax"] = values["tax"];
    fund["NetIncome1"] = values["net_profit_is"]; # 净利润
    fund["MinorityIntIncome"] = values["minority_int_inc"];
    fund["NetIncome2"] = values["np_belongto_parcomsh"]; # 归属母公司股东的净利润

    # --- 2018.4 修正 ---
    # fund["OperatingProfit1"] = fund["TotalRevenue_Q - fund["TotalExpense_Q;
    fund["IncomeBeforeDepAmort"] = fund["OperatingProfit2"] + fund["DepAmort"];
    fund["EBT"] = fund["NetIncome1"] + fund["Tax"];
    fund["EBIT"] = fund["EBT"] + fund["InterestExpense"];
    fund["EBITDA"] = fund["EBIT"] + fund["DepAmort"];

    # ---B/S Sheet---
    # ---Current Asset---
    fund["TotalAsset"] = values["tot_assets"];
    fund["CurrentAsset"] = values["tot_cur_assets"];
    fund["CashEquivalents"] = values["monetary_cap"] + values["settle_rsrv"] + values["cash_deposits_central_bank"] + values["asset_dep_oth_banks_fin_inst"] + values["precious_metals"] + values["mrgn_paid"];

    #
    fund["STInvest"] = Calc_STInvest(values)

    #
    fund["Receivable"] = values["notes_rcv"] + values["acct_rcv"] + values["int_rcv"] + values["prem_rcv"] + values["oth_rcv"];
    fund["PrepaidExpense"] = values["prepay"]; # 2018.1 移除了 deferred_tax_Asset
    fund["Inventory"] = values["inventories"];
    fund["OtherCurrentAsset"] = values["non_cur_assets_due_within_1y"] + values["oth_cur_assets"];

    # ---Non current Asset---
    fund["NonCurrentAsset"] = values["tot_non_cur_assets"];
    fund["PPE"] = values["fix_assets"] + values["const_in_prog"];
    fund["LTInvest"] = values["long_term_eqy_invest"] + \
                       values["loans_and_adv_granted"] + \
                       values["fin_assets_avail_for_sale"] + \
                       values["held_to_mty_invest"] + \
                       values["invest_real_estate"] + values["time_deposits"] + values["insured_pledge_loan"];
    fund["GoodWillIntangible"] = values["goodwill"] + values["intang_assets"] + values["r_and_d_costs"]; # 2018.4 新加入开发支出
    fund["DeferredTaxAsset"] = values["deferred_tax_assets"]  # 2018.4 新建字段
    fund["OtherNonCurrentAsset"] = values["long_term_rec"] + values["long_term_deferred_exp"] + values["oth_non_cur_assets"] + values["oth_assets"];

    #---Current Liab---
    fund["TotalLiab"] = values["tot_liab"];
    fund["CurrentLiab"] = values["tot_cur_liab"];
    fund["STDebt"] = values["st_borrow"] + \
                    values["loans_oth_banks"] + values["tradable_fin_liab"] + values["fund_sales_fin_assets_rp"] + \
                     values["liab_dep_oth_banks_fin_inst"] + values["derivative_fin_liab"] + values["cust_bank_dep"] + \
                     values["insured_deposit_invest"] + values["acting_trading_sec"] + values["acting_uw_sec"];
                    # 2018.4 添加字段 borrow_central_bank
    if "borrow_central_bank" in values:
        fund["STDebt"] = fund["STDebt"] + values["borrow_central_bank"]

    fund["Payable"] = values["acct_payable"] + values["empl_ben_payable"] + values["dvd_payable"] + values["int_payable"] + values["taxes_surcharges_payable"] + values["oth_payable"] + values["notes_payable"] + values["dvd_payable_insured"];
    fund["UnearnedRevenue"] = values["adv_from_cust"] + values["prem_received_adv"]; # 2018.1 移除了 deferred_tax_liab

    fund["OtherCurrentLiab"] = values["non_cur_liab_due_within_1y"] + values["oth_cur_liab"] + values["agency_bus_liab"];

    #---Non Current Liab---
    fund["NonCurrentLiab"] = values["tot_non_cur_liab"];
    fund["LTDebt"] = values["lt_borrow"] + values["bonds_payable"] + values["life_insur_rsrv"] + values["lt_health_insur_v"];
    fund["DeferredTaxLiability"] = values["deferred_tax_liab"]  # 2018.4 新建字段
    # 2018.4 添加递延收益
    fund["OtherNonCurrentLiab"] = values["provisions"] + values["oth_non_cur_liab"] + values["oth_liab"] + values["deferred_inc_non_cur_liab"];

    #---Equity---
    fund["TotalEquity"] = values["tot_equity"];
    fund["PaidinCapital"] = values["cap_stk"] + values["other_equity_instruments_pre"] - values["tsy_stk"];
    fund["CommonStock"] = values["cap_stk"]
    fund["PreferredStock"] = values["other_equity_instruments_pre"]
    fund["CapitalSurplus"] = values["cap_rsrv"];
    fund["EarnedSurplus"] = values["surplus_rsrv"];
    fund["CapitalProvision"] = values["prov_nom_risks"];
    fund["SpecialReserve"] = values["special_rsrv"];
    fund["Reserve"] = values["cap_rsrv"] + values["surplus_rsrv"] + values["prov_nom_risks"] + values["special_rsrv"]
    fund["MinorityInterest"] = values["minority_int"];
    fund["RetainedEarning"] = values["undistributed_profit"];
    fund["ComprehensiveIncome"] = values["other_compreh_inc_bs"]

    # ---CashFlow---
    fund["OperatingCashFlow"] = values["net_cash_flows_oper_act"];
    fund["InvestingCashFlow"] = values["net_cash_flows_inv_act"];
    fund["FinancingCashFlow"] = values["net_cash_flows_fnc_act"];
    fund["CapitalExpenditure"] = values["cash_pay_acq_const_fiolta"];
    fund["SalePPE"] = values["net_cash_recp_disp_fiolta"];
    fund["DebtIssue"] = values["proc_issue_bonds"] + values["cash_recp_borrow"];
    fund["DebtReduce"] = values["cash_prepay_amt_borr"];
    fund["EquityIssue"] = values["cash_recp_cap_contrib"];
    fund["FreeCashFlow"] = fund["OperatingCashFlow"] - fund["CapitalExpenditure"];

    # 筹资活动现金流出小计 - 偿还债务支付的现金 - 分配股利、利润或偿付利息支付的现金 - 支付其他与筹资活动有关的现金
    fund["EquityReduce"] = values["stot_cash_outflows_fnc_act"] - values["cash_prepay_amt_borr"] - values["cash_pay_dist_dpcp_int_exp"] - values["other_cash_pay_ral_fnc_act"];

    # ---Dividend 该数据不再作为标准化报表数据的一部分---
    # 这个数据不是很准确,只能按年取
    # fund["Dividend_Y"] = values["div_aualaccmdiv"];
    # 这个数据包含了，分配股利、利润或偿付利息支付的现金
    fund["PayDividend"] = values["cash_pay_dist_dpcp_int_exp"];

    # ---Financials---
    # ---Static/LYR---
    fund["EPS"] = values["eps_basic"];
    fund["BPS"] = values["bps"];
    fund["InterestCoverage"] = values["ebitdatointerest"];
    fund["ProfitMargin"] = values["netprofitmargin"];
    fund["ROE"] = values["roe"];
    fund["ROA"] = values["roa"];

    # ---TTM Rolling---
    fund["EPS_TTM"] = values["eps_ttm"];
    fund["PriceEarning_TTM"] = values["pe_ttm"];
    fund["PriceBook"] = values["pb_lf"];
    fund["PriceSales_TTM"] = values["ps_ttm"];

    # ---Other---
    fund["WorkingCapital"] = values["workingcapital"];
    fund["NetWorkingCapital"] = values["networkingcapital"];
    fund["TotalShares"] = values["total_shares"];
    fund["FreeShares"] = values["free_float_shares"];

    fund["Close"] = values["close"];

    # ---Special Case Handeling---
    if fund["CurrentAsset"] == 0:
        # print(symbol + " " + reportDate + " Error CurrentAsset == 0")
        fund["CurrentAsset"] = fund["CashEquivalents"] + fund["STInvest"] + fund["Receivable"] \
                               + fund["PrepaidExpense"] + fund["Inventory"] + fund["OtherCurrentAsset"];

    if fund["NonCurrentAsset"] == 0:
        # print(symbol + " " + reportDate + " Error NonCurrentAsset == 0 ")
        fund["NonCurrentAsset"] = fund["PPE"] + fund["LTInvest"] + fund["GoodWillIntangible"] \
                                  + fund["DeferredTaxAsset"] + fund["OtherNonCurrentAsset"];

    if fund["CurrentLiab"] == 0:
        #print(symbol + " " + reportDate + " Error CurrentLiab == 0 ")
        fund["CurrentLiab"] = fund["STDebt"] + fund["Payable"] + fund["UnearnedRevenue"] + fund["OtherCurrentLiab"];

    if fund["NonCurrentLiab"] == 0:
        # print(symbol + " " + reportDate + " Error NonCurrentLiab == 0 ")
        fund["NonCurrentLiab"] = fund["LTDebt"] + fund["DeferredTaxLiability"] + fund["OtherNonCurrentLiab"];

    if fund["WorkingCapital"] == 0:
        # print(symbol + " " + reportDate + " Error WorkingCapital == 0 ")
        fund["WorkingCapital"] = fund["CurrentAsset"] - fund["CurrentLiab"]
        # fund["NetWorkingCapital"]

    # ---Derivatives---
    fund["NOA"] = (fund["TotalAsset"] - fund["CashEquivalents"]) - (fund["TotalLiab"] - fund["LTDebt"] - fund["STDebt"]);
    #fund["BookValue"] = fund["TotalEquity"];

    # ---Derivatives-Financials---

    # ---2018-4-23 不在计算 DPS_Y---
    #if fund["TotalShares"] == 0:
    #    fund["DPS_Y"] = 0
    #    print(symbol + " " + reportDate + " Error TotalShares == 0 ")
    #else:
    #    fund["DPS_Y"] = fund["Dividend_Y"] / fund["TotalShares"];

    # if fund["NetIncome1"] == 0:
    #    print(symbol + " " + reportDate + " Error NetIncome1 == 0 ")
    #else:
    #    fund["DividendPayoutRatio"] = (fund["Dividend_Y"] * 0.25) / fund["NetIncome1"];

    if fund["TotalEquity"] == 0:
        print(symbol + " " , reportDate , " Error TotalEquity == 0 ")
        fund["TotalEquity"] = fund["TotalAsset"] - fund["TotalLiab"]
    if fund["TotalEquity"] != 0:
        fund["DebtEquity"] = fund["TotalLiab"] / fund["TotalEquity"];
    else:
        fund["DebtEquity"] = math.nan

    # ---Dividend---
    if "div_cashbeforetax2" in values:
        fund["DividendCashBeforeTax"] = values["div_cashbeforetax2"]
    else:
        fund["DividendCashBeforeTax"] = 0
    #
    if "div_cashaftertax2" in values:
        fund["DividendCashAfterTax"] = values["div_cashaftertax2"]
    else:
        fund["DividendCashAfterTax"] = 0

    if "div_stock2" in values:
        fund["DividendStock"] = values["div_stock2"]
    else:
        fund["DividendStock"] = 0

    if "div_capitalization2" in values:
        fund["DividendCapitalization"] = values["div_capitalization2"]
    else:
        fund["DividendCapitalization"] = 0

    #
    # fund["SegmentSalesByProduct"] = values["segment_sales"]

    #
    #fund["Top10HolderShares"] = values["holder_top10quantity"]
    #fund["Top10FreeHolderShares"] = values["holder_top10liqquantity"]
    #fund["SharesHoldByInstitutes"] = values["holder_totalbyinst"]
    #fund["SharesHoldByGeneral"] = values["holder_totalbygeneralcorp"]
    #fund["SharesHoldByMutualFund"] = values["holder_totalbyfund"]
    #fund["SharesHoldByBrokerHouse"] = values["holder_totalbybysec"] + values["holder_totalbybywmp"]
    #fund["SharesHoldByInsurance"] = values["holder_totalbyinsur"]
    #
    return fund


# ---unfinished---
def GetFundamentalProfileDataFrame(database, stdDateTime, fields=[], fundamentalsBySymbol={}):
    #
    filter = {}
    ipoDate = stdDateTime
    filter["IPO_Date"] = {"$gt": ipoDate}
    instruments = database.findWithFilter("Instruments", "Stock", filter)

    # --- Loop instruments ---
    for instrument in instruments:
        symbol = instrument["Symbol"]
        if symbol not in fundamentalsBySymbol:
            fundamentals = database.getDataSeries(symbol + "_Fundamental")
            fundamentalsBySymbol[symbol] = fundamentals
        fundamentals = fundamentalsBySymbol[symbol]


def MissingReports():
    #
    missingReports = []
    #
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2007, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2008, 6, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2008, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2009, 6, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2009, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2010, 6, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2010, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2011, 6, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2011, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2012, 6, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2012, 9, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2012, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2013, 6, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2013, 9, 30)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2013, 12, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2014, 3, 31)})
    missingReports.append({"Symbol": "000166.SZ", "ReportDate": datetime(2014, 12, 31)})

    #
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2007, 6, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2007, 12, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2008, 3, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2008, 6, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2008, 9, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2009, 6, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2009, 3, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2009, 9, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2009, 12, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2010, 3, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2010, 6, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2010, 9, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2010, 12, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2011, 3, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2011, 6, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2011, 9, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2011, 12, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2012, 3, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2012, 6, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2012, 9, 30)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2012, 12, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2013, 3, 31)})
    missingReports.append({"Symbol": "000333.SZ", "ReportDate": datetime(2013, 6, 30)})

    #
    missingReports.append({"Symbol": "000620.SZ", "ReportDate": datetime(2008, 9, 30)})
    missingReports.append({"Symbol": "000748.SZ", "ReportDate": datetime(2016, 12, 31)})
    missingReports.append({"Symbol": "000748.SZ", "ReportDate": datetime(2017, 3, 31)})
    missingReports.append({"Symbol": "600005.SH", "ReportDate": datetime(2016, 12, 31)})
    missingReports.append({"Symbol": "600005.SH", "ReportDate": datetime(2017, 3, 31)})
    missingReports.append({"Symbol": "000522.SZ", "ReportDate": datetime(2013, 3, 31)})
    missingReports.append({"Symbol": "000562.SZ", "ReportDate": datetime(2014, 12, 31)})
    missingReports.append({"Symbol": "000602.SZ", "ReportDate": datetime(2013, 6, 30)})
    missingReports.append({"Symbol": "000618.SZ", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "000699.SZ", "ReportDate": datetime(2007, 3, 31)})
    missingReports.append({"Symbol": "000763.SZ", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "000765.SZ", "ReportDate": datetime(2005, 3, 31)})
    missingReports.append({"Symbol": "000765.SZ", "ReportDate": datetime(2005, 6, 30)})
    missingReports.append({"Symbol": "000817.SZ", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "200041.SZ", "ReportDate": datetime(2009, 9, 30)})
    missingReports.append({"Symbol": "600002.SH", "ReportDate": datetime(2006, 3, 31)})
    missingReports.append({"Symbol": "600092.SH", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "600092.SH", "ReportDate": datetime(2006, 3, 31)})
    missingReports.append({"Symbol": "600092.SH", "ReportDate": datetime(2006, 6, 30)})
    missingReports.append({"Symbol": "600092.SH", "ReportDate": datetime(2006, 9, 30)})
    missingReports.append({"Symbol": "600102.SH", "ReportDate": datetime(2011, 12, 31)})
    missingReports.append({"Symbol": "600205.SH", "ReportDate": datetime(2007, 3, 31)})
    missingReports.append({"Symbol": "600253.SH", "ReportDate": datetime(2013, 6, 30)})
    missingReports.append({"Symbol": "600263.SH", "ReportDate": datetime(2011, 12, 31)})
    missingReports.append({"Symbol": "600286.SH", "ReportDate": datetime(2006, 12, 31)})
    missingReports.append({"Symbol": "600286.SH", "ReportDate": datetime(2007, 3, 31)})
    missingReports.append({"Symbol": "600296.SH", "ReportDate": datetime(2007, 3, 31)})
    missingReports.append({"Symbol": "600553.SH", "ReportDate": datetime(2010, 12, 31)})
    missingReports.append({"Symbol": "600591.SH", "ReportDate": datetime(2009, 12, 31)})
    missingReports.append({"Symbol": "600607.SH", "ReportDate": datetime(2009, 12, 31)})
    missingReports.append({"Symbol": "600659.SH", "ReportDate": datetime(2005, 6, 30)})
    missingReports.append({"Symbol": "600659.SH", "ReportDate": datetime(2005, 9, 30)})
    missingReports.append({"Symbol": "600659.SH", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "600772.SH", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "600772.SH", "ReportDate": datetime(2006, 3, 31)})
    missingReports.append({"Symbol": "600772.SH", "ReportDate": datetime(2006, 6, 30)})
    missingReports.append({"Symbol": "600772.SH", "ReportDate": datetime(2006, 9, 30)})
    missingReports.append({"Symbol": "600786.SH", "ReportDate": datetime(2007, 12, 31)})
    missingReports.append({"Symbol": "600799.SH", "ReportDate": datetime(2005, 12, 31)})
    missingReports.append({"Symbol": "600842.SH", "ReportDate": datetime(2009, 12, 31)})
    missingReports.append({"Symbol": "600991.SH", "ReportDate": datetime(2011, 12, 31)})
    missingReports.append({"Symbol": "T00018.SH", "ReportDate": datetime(2006, 9, 30)})

    return missingReports


# ---统计指定日期的报告数量（掌握目前更新进度）---
def Check_Fundamental_DownloadProgress(database, reportDate):
    #
    target = Gadget.ToDateTimeString(reportDate)
    #
    count = 0
    instruments = Gadget.FindListedInstrument(database, reportDate)
    statements = database.Find("Stock", "Fundamental_Basic", filter={"Report_Date": reportDate})
    instrumentCount = len(instruments)
    statementCount = len(statements)

    #for instrument in instruments:
    #    if count % 100 == 0:
    #        print("Process", count)
    #    symbol = instrument["Symbol"]
    #    statements = database.find("Fundamental", symbol + "_Fundamental", query={"ReportDate":target})
    #    if len(statements) != 0:
    #        count += 1

    #
    print("Collected Reports", statementCount, "of total", instrumentCount, format(statementCount/instrumentCount, '.0%'), " @ ", target)


def Downlonad_Fundamental():
    pass

if __name__ == '__main__':
    #
    from Core.Config import *
    pathfilename = os.getcwd() + "\..\Config\config2.json"
    config = Config(pathfilename)
    database = config.DataBase("JDMySQL")
    logger = config.Logger("WindFundamental")

    # ---统计指定日期的报告---
    # datetime2 = datetime(2020, 3, 31)
    # DataProcess.Check_Fundamental_DownloadProgress(database, datetime2)
    # Statistics_Release_Progress_at_Specific_Day_in_Hist(database, 4, 22, period=1)
    # Statistics_ReleaseDateCount()
    # Statistics(database)

    Wind.w.start() # 启动Wind API

    # cold start
    # Batch_Download_Fundamentals(database, datetime1, datetime2, instruments=[], startIndex=0, logger=None)

    # ---实验性下载一期---
    reportDate = datetime(2019, 12, 31)
    instrument = database.Find("Financial_Data","Instrument_Stock", filter={"symbol":"000005.SZ"})
    instrument = instrument[0]
    Download_Fundamentals(database, instrument, reportDate, logger=None)

    # ---获取季度财报---
    datetime1 = datetime(2020, 6, 30)
    datetime2 = datetime(2020, 9, 30)
    # DataProcess.Batch_Download_Fundamentals(database, datetime1, datetime2, startIndex=0, logger=logger)
    Batch_Download_Fundamentals_Adv(database, datetime1, datetime2, startIndex=0, logger=logger)

    # 检查下载进度
    reportDates = Gadget.GenerateReportDates(datetime1, datetime2)
    for reportDate in reportDates:
        DataProcess.Check_Fundamental_DownloadProgress(database, reportDate)


